<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
    "http://www.w3.org/TR/html4/loose.dtd">
<html lang="zh-CN">
<head>
    <title>Socket测试</title>
</head>
<link rel="stylesheet" href="">
<body>
<p><img style='width:5px;height:5px' src="https://raw.githubusercontent.com/laravel/art/master/logo-lockup/5%20SVG/2%20CMYK/1%20Full%20Color/laravel-logolockup-cmyk-red.svg"> CREMB-OA</p>

<div>
    <p>登陆凭证:<input type="text" id="token"></p>
    <p>登陆类型:<input type="text" id="user_type" value="user"></p>
</div>
<div style="width: 50%;display: inline-block;float: left">
    <p><span>连接地址:</span><input type="text" id="host" value="ws://0.0.0.0:20270" style="width: 60%">
        <button id="connect">连接</button>
    </p>
    <p><textarea name="content" cols="100" id="content" rows="30"></textarea></p>
    <p>
        <button id="send">发送</button>
    </p>
</div>
<div style="width: 50%;display: inline-block;">
    <p><span>日志</span></p>
    <textarea name="log" cols="100" rows="30" id="log" disabled readonly></textarea>
</div>
</body>
</html>
<script type="text/javascript">

    var event = {
        thisType: '',
        elementData: {},
        eventData: [],
        element: function (type, nowElement) {

            if (this.elementData[type] !== undefined && !nowElement) {
                return this.elementData[type];
            }

            var element = document.getElementById(type);

            if (!nowElement) {
                this.elementData[type] = element;
            }

            return element;
        },
        setThisType: function (value) {
            this.thisType = value;
            return this;
        },
        on: function (event, closure) {
            var eventListener = this.element(this.thisType).addEventListener(event, closure);
            this.thisType = '';
            return eventListener;
        },
        value: function (values) {
            if (values) {
                this.element(this.thisType).value = values;
                this.thisType = '';
                return values;
            } else {
                var data = this.element(this.thisType).values;
                this.thisType = '';
                return data;
            }
        },
        listen: function (typeName, closure) {
            this.eventData[this.getType(typeName)] = closure;
        },
        trigger: function (typeName, data) {
            return this.eventData[this.getType(typeName)](data);
        },
        getType: function (typeName) {
            return 'on' + typeName.charAt(0).toUpperCase() + typeName.slice(1);
        }
    };

    $ = function (value) {
        return event.setThisType(value);
    }


    event.listen('test', function (data) {
        console.log(data);
    });

    event.listen('success ', function (data) {
        console.log(data);
    });

    var socket = function () {
        this.ws = null;
        this.timerNum = 10000;
        this.timer = null;
        this.isOpen = false;
    };

    socket.prototype.getStatus = function () {
        return this.isOpen;
    }

    socket.prototype.connect = function () {
        this.ws = new WebSocket(event.element('host').value + '?type=' + event.element('user_type').value + "&token=" + event.element('token').value);
        this.ws.onopen = this.onOpen.bind(this);
        this.ws.onerror = this.onError.bind(this);
        this.ws.onmessage = this.onMessage.bind(this);
        this.ws.onclose = this.onClose.bind(this);
    };

    socket.prototype.ping = function () {
        var that = this;
        this.timer = setInterval(function () {
            that.send({type: 'ping'});
        }, this.timerNum);
    }

    socket.prototype.send = function (data) {
        data = JSON.stringify(data);
        this.log(true, data);
        return this.ws.send(data);
    }

    socket.prototype.onOpen = function () {
        this.isOpen = true;
        this.ping();
        event.element('send').disabled = false;
    }

    socket.prototype.onError = function (e) {
        console.log(e);
        this.log(e);
    }

    socket.prototype.onMessage = function (res) {
        this.log(false, res.data);
        var data = JSON.parse(res.data);
        var type = 'Test';
        if (data.type !== undefined) {
            type = data.type;
        }
        return event.trigger(type, data.data !== undefined ? data.data : {});
    }

    socket.prototype.onClose = function () {
        if (this.timer) {
            clearInterval(this.timer);
        }
        this.isOpen = false;
    }

    socket.prototype.log = function (ispush, data) {
        event.element('log').value += '[' + (ispush ? '送达' : '接收') + '][' + new Date().Format("yyyy-MM-dd hh:mm:ss") + ']' + data + '\n';
        event.element('log').scrollTop = event.element('log').scrollHeight;
    }

    // 对Date的扩展，将 Date 转化为指定格式的String
    // 月(M)、日(d)、小时(h)、分(m)、秒(s)、季度(q) 可以用 1-2 个占位符，
    // 年(y)可以用 1-4 个占位符，毫秒(S)只能用 1 个占位符(是 1-3 位的数字)
    // 例子：
    // (new Date()).Format("yyyy-MM-dd hh:mm:ss.S") ==> 2006-07-02 08:09:04.423
    // (new Date()).Format("yyyy-M-d h:m:s.S") ==> 2006-7-2 8:9:4.18

    Date.prototype.Format = function (fmt) { // author: meizz
        var o = {
            "M+": this.getMonth() + 1, // 月份
            "d+": this.getDate(), // 日
            "h+": this.getHours(), // 小时
            "m+": this.getMinutes(), // 分
            "s+": this.getSeconds(), // 秒
            "q+": Math.floor((this.getMonth() + 3) / 3), // 季度
            "S": this.getMilliseconds() // 毫秒
        };
        if (/(y+)/.test(fmt))
            fmt = fmt.replace(RegExp.$1, (this.getFullYear() + "").substr(4 - RegExp.$1.length));
        for (var k in o)
            if (new RegExp("(" + k + ")").test(fmt)) fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length)));
        return fmt;
    }

    var nowsocket = new socket();

    if (nowsocket.getStatus() === false) {
        event.element('send').disabled = true;
    }


    $('connect').on('click', function () {
        nowsocket.connect();
    });

    $('send').on('click', function () {
        nowsocket.send({type: 'message', data: event.element('content').value});
        event.element('content').value = '';
    });

</script>
